%% NOMA主函数 - 非正交多址仿真
% 本程序模拟了非正交多址技术，这是第五代移动通信(5G)使用的多址接入技术
% 在NOMA中，不同用户在功率域进行复用，利用连续干扰消除(SIC)技术解码

clear all;
close all;
clc;

%% 参数设置
num_users = 2;            % 用户数量（典型NOMA场景中2-3个用户共享一个资源）
num_resource_blocks = 1;  % 资源块数量
num_bits = 1000;          % 每个用户的比特数
snr_dB = 20;              % 信噪比(dB)
modulation = 'QPSK';      % 调制方式
distance_near = 200;      % 近用户距离(m)
distance_far = 800;       % 远用户距离(m)
pathloss_exp = 3.5;       % 路径损耗指数

% 信道质量参数计算
channel_gain_near = distance_near^(-pathloss_exp);  % 近用户信道增益
channel_gain_far = distance_far^(-pathloss_exp);    % 远用户信道增益

fprintf('信道增益比例: %.2f dB\n', 10*log10(channel_gain_near/channel_gain_far));

%% 功率分配系数
% 在NOMA中，远用户分配更多的功率
alpha = power_allocation(channel_gain_near, channel_gain_far);
alpha_near = alpha(1);  % 近用户功率分配系数
alpha_far = alpha(2);   % 远用户功率分配系数

fprintf('功率分配系数:\n');
fprintf('  - 近用户: %.2f (%.2f dB)\n', alpha_near, 10*log10(alpha_near));
fprintf('  - 远用户: %.2f (%.2f dB)\n', alpha_far, 10*log10(alpha_far));

%% 生成用户数据
user_bits = cell(1, num_users);
user_symbols = cell(1, num_users);

% 生成每个用户的随机比特
for u = 1:num_users
    user_bits{u} = randi([0 1], 1, num_bits);
    % 调制用户数据
    user_symbols{u} = modulate_symbols(user_bits{u}, modulation);
end

%% NOMA信号叠加
% 对每个资源块，叠加不同用户的信号
superposed_signals = cell(1, num_resource_blocks);

for rb = 1:num_resource_blocks
    % 实际上，用户可以分配到不同的资源块
    % 为简化，我们假设所有用户共享所有资源块
    
    % 近用户（用户1）和远用户（用户2）
    near_user_symbols = user_symbols{1};
    far_user_symbols = user_symbols{2};
    
    % 使用分配的功率系数叠加信号
    superposed_signal = sqrt(alpha_near) * near_user_symbols + sqrt(alpha_far) * far_user_symbols;
    superposed_signals{rb} = superposed_signal;
    
    fprintf('资源块 %d 上叠加了 %d 个用户的信号\n', rb, num_users);
end

%% 通过无线信道
received_signals = cell(1, num_resource_blocks);

for rb = 1:num_resource_blocks
    % 添加信道效应
    received_near = apply_channel(superposed_signals{rb}, channel_gain_near, snr_dB);
    received_far = apply_channel(superposed_signals{rb}, channel_gain_far, snr_dB);
    
    % 存储各用户接收到的信号
    received_signals{rb} = {received_near, received_far};
end

%% 接收端SIC解码
decoded_bits = cell(1, num_users);
ber = zeros(1, num_users);

for rb = 1:num_resource_blocks
    % 获取当前资源块上各用户接收到的信号
    received_near = received_signals{rb}{1};
    received_far = received_signals{rb}{2};
    
    % 近用户解码 - 使用SIC技术
    % 1. 首先解码功率较大的远用户信号
    % 2. 从接收信号中减去重构的远用户信号
    % 3. 然后解码自己的信号
    [decoded_far_by_near, ~] = decode_symbol(received_near, modulation, 'far');
    reconstructed_far = modulate_symbols(decoded_far_by_near, modulation);
    after_sic = received_near - sqrt(alpha_far * channel_gain_near) * reconstructed_far;
    [decoded_near, ~] = decode_symbol(after_sic, modulation, 'near');
    
    % 远用户直接解码自己的信号
    % 由于功率分配，远用户的信号功率较大，近用户的信号被视为噪声
    [decoded_far, ~] = decode_symbol(received_far, modulation, 'far');
    
    % 存储解码结果
    decoded_bits{1} = decoded_near(1:num_bits);  % 近用户
    decoded_bits{2} = decoded_far(1:num_bits);   % 远用户
end

%% 计算误码率
for u = 1:num_users
    errors = sum(user_bits{u} ~= decoded_bits{u});
    ber(u) = errors / num_bits;
    
    fprintf('用户 %d 的误码率: %.6f\n', u, ber(u));
end

%% 绘制性能结果
plot_noma_results(user_symbols, superposed_signals{1}, received_signals{1}, alpha, ber);

%% 绘制NOMA功率域复用示意图
visualize_noma(alpha_near, alpha_far, distance_near, distance_far);

fprintf('NOMA仿真完成!\n'); 